package top.zdkhqh;

import top.zdkhqh.bean.PictureGallery;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class ImageUtil {


    /**
     * 小图片贴到大图片形成一张图(合成)
     */
    public static void overlapImage(String bigPath, List<String> smallPath, String outFile) {
        try {
            BufferedImage big = ImageIO.read(new File(bigPath));
            //正方形
            int sideLength = (int) Math.sqrt(big.getWidth() * big.getHeight() / smallPath.size());
            Graphics2D g = big.createGraphics();
            //透明度 ，值从0-1.0，依次变得不透明
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4f));
            int x = 0;
            int y = 0;
            for (String s : smallPath) {
                if (big.getWidth() - x <= 0) {
                    x = 0;
                    y += sideLength;
                }
                g.drawImage(ImageIO.read(new File(s)), x, y, sideLength, sideLength, null);
                x += sideLength;
            }
            // 释放对象 透明度设置结束
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.dispose();
            ImageIO.write(big, outFile.split("\\.")[1], new File(outFile));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 马赛克化. 马赛克尺寸。即每一个矩形的长宽
     *
     * @return
     * @throws Exception
     */
    public static void mosaic(String srcPath, String outFile, int sideLength, int size) {
        File file = new File(srcPath);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        BufferedImage spinImage = new BufferedImage(bi.getWidth(),
                bi.getHeight(), BufferedImage.TYPE_INT_RGB);

        int x = 0;
        int y = 0;
        // 绘制马赛克(绘制矩形并填充颜色)
        Graphics gs = spinImage.getGraphics();
        for (int p = 0; p < size; p++) {
            List<Integer> redList = new ArrayList<>();
            List<Integer> greenList = new ArrayList<>();
            List<Integer> blueList = new ArrayList<>();
            boolean isOk = true;
            for (int i = x; i < x + sideLength; i++) {
                for (int j = y; j < y + sideLength; j++) {
                    int rgb = 0;
                    try {
                        rgb = spinImage.getRGB(i, j);
                        redList.add((rgb & 0xff0000) >> 16);
                        greenList.add((rgb & 0xff00) >> 8);
                        blueList.add(rgb & 0xff);
                    } catch (Exception e) {
                        isOk = false;
                    }
                }
            }
            if (isOk) {
                int redAvg = (int) (redList.stream().mapToDouble(e -> e).average().getAsDouble());
                int greenAvg = (int) (greenList.stream().mapToDouble(e -> e).average().getAsDouble());
                int blueAvg = (int) (blueList.stream().mapToDouble(e -> e).average().getAsDouble());
                Color color = new Color(redAvg, greenAvg, blueAvg);
                gs.setColor(color);
                gs.fillRect(x, y, sideLength, sideLength);
            }
            x += sideLength;
            if (spinImage.getWidth() - x <= 0) {
                x = 0;
                y += sideLength;
            }
        }
        gs.dispose();
        try {
            ImageIO.write(spinImage, outFile.split("\\.")[1], new File(outFile));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 相似覆盖
     *
     * @param srcPath 目标单张图片
     * @param url     小图图片库
     * @param size    小图图片数量
     * @param limit   每张图限制出现次数
     * @param outFile 输出路径
     */
    public static void similarCovering(String srcPath, String url, int size, Integer limit, String outFile) {
        PictureGallery pictureGallery = new PictureGallery(url, size, limit);
        try {
            BufferedImage big = ImageIO.read(new File(srcPath));
            //正方形边长
            int oldSideLength = (int) Math.sqrt(big.getWidth() * big.getHeight() / pictureGallery.getSize());
            int sideLength = oldSideLength;
            Graphics2D g = big.createGraphics();
            int x = 0;
            int y = 0;
            for (int p = 0; p < pictureGallery.getSize(); p++) {
                List<Integer> redList = new ArrayList<>();
                List<Integer> greenList = new ArrayList<>();
                List<Integer> blueList = new ArrayList<>();
                boolean isOk = true;
                for (int i = x; i < x + sideLength; i++) {
                    for (int j = y; j < y + sideLength; j++) {
                        int rgb = 0;
                        try {
                            rgb = big.getRGB(i, j);
                            redList.add((rgb & 0xff0000) >> 16);
                            greenList.add((rgb & 0xff00) >> 8);
                            blueList.add(rgb & 0xff);
                        } catch (Exception e) {
                            isOk = false;
                        }
                    }
                }
                if (isOk) {
                    int redAvg = (int) (redList.stream().mapToDouble(e -> e).average().getAsDouble());
                    int greenAvg = (int) (greenList.stream().mapToDouble(e -> e).average().getAsDouble());
                    int blueAvg = (int) (blueList.stream().mapToDouble(e -> e).average().getAsDouble());
                    String mostSimilarUrl = pictureGallery.getMostSimilar(new Color(redAvg, greenAvg, blueAvg));
                    g.drawImage(ImageIO.read(new File(mostSimilarUrl)), x, y, sideLength, sideLength, null);
                }

                x += sideLength;
                if (big.getWidth() - x <= 0) {
                    x = 0;
                    y += sideLength;
                }
            }
            g.dispose();
            ImageIO.write(big, outFile.split("\\.")[1], new File(outFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取一张图片的平均rgb值
     */
    public static int getAverageRGB(String picUrl) {
        File file = new File(picUrl);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int width = bi.getWidth();
        int height = bi.getHeight();
        List<Integer> redList = new ArrayList<>();
        List<Integer> greenList = new ArrayList<>();
        List<Integer> blueList = new ArrayList<>();
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                int rgb = bi.getRGB(i, j);
                redList.add((rgb & 0xff0000) >> 16);
                greenList.add((rgb & 0xff00) >> 8);
                blueList.add(rgb & 0xff);
            }
        }
        int redAvg = (int) (redList.stream().mapToDouble(e -> e).average().getAsDouble());
        int greenAvg = (int) (greenList.stream().mapToDouble(e -> e).average().getAsDouble());
        int blueAvg = (int) (blueList.stream().mapToDouble(e -> e).average().getAsDouble());
        return new Color(redAvg, greenAvg, blueAvg).getRGB();
    }

}